package com.fnd.med.utils;

import com.bstek.dorado.console.Logger;
import com.bstek.dorado.data.provider.Page;

import java.io.Serializable;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Named;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

@Named
public class BaseDao {
	private static Logger logger = Logger.getLog(BaseDao.class);

	@Inject
	private SessionFactory sessionFactory;

	@SuppressWarnings("unchecked")
	public <T> T get(Class<T> clazz, Serializable seq) {
		return (T) getSession().get(clazz, seq);
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> get(Class<T> clazz, List<Integer> seqs) {
		Criteria criteria = getSession().createCriteria(clazz);
		criteria.add(Restrictions.in("serverSeq", seqs));
		return criteria.list();
	}

	public Session getSession() {
		return sessionFactory.getCurrentSession();
		
//		logger.info("getSession");
//		Session session = null;
//		try{
//			session = sessionFactory.getCurrentSession();
//			
//		}catch(Exception e){
//			session = null;
//		}
//		if(null==session){
//			session = sessionFactory.openSession();
//		}
//		return session;
	}

	public Serializable save(Object obj) {
		return getSession().save(obj);
	}

	public void saveOrUpdate(Object obj) {
		getSession().saveOrUpdate(obj);
	}

	public void update(Object obj) {
		getSession().update(obj);
	}

	public void delete(Object obj) {
		getSession().delete(obj);
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> getAll(DetachedCriteria detachedCriteria) {
		return detachedCriteria.getExecutableCriteria(getSession()).list();
	}

	public <T> List<T> getAll(int pageNo, int pageSize,
			DetachedCriteria detachedCriteria) {
		Criteria criteria = detachedCriteria
				.getExecutableCriteria(getSession());
		return getAll(pageNo, pageSize, criteria);
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> getAll(int pageNo, int pageSize, Criteria criteria) {
		criteria.setFirstResult((pageNo - 1) * pageSize);
		criteria.setFetchSize(pageSize);
		return criteria.list();
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> getAll(Criteria criteria) {
		return criteria.list();
	}

	public SessionFactory getSessionFactory() {
		return this.sessionFactory;
	}

	public Long count(DetachedCriteria detachedCriteria) {
		return Long.valueOf(count(detachedCriteria
				.getExecutableCriteria(getSession())));
	}

	public long count(Criteria criteria) {
		criteria.setProjection(Projections.rowCount());
		return ((Long) criteria.uniqueResult()).longValue();
	}

	public <T> List<T> getAll(Page<?> page, DetachedCriteria detachedCriteria) {
		page.setEntityCount((int) count(
				(DetachedCriteria) MeapsUtil.cope(detachedCriteria))
				.longValue());
		return getAll(page.getPageNo(), page.getPageSize(),
				detachedCriteria.getExecutableCriteria(getSession()));
	}
	
	public <T> T getUnique(DetachedCriteria detachedCriteria){
		return getUnique(detachedCriteria.getExecutableCriteria(getSession()));
	}

	@SuppressWarnings("unchecked")
	private <T> T getUnique(Criteria criteria) {
		return (T) criteria.uniqueResult();
	}
	
	
}